REM Language: SmallBASIC 0.12.6 (Linux 32-bit) REM Purpose: A Base64 Encoder/Decoder UNIT. REM File name: base64.bas REM Unit name: base64 REM Version: 1.0.1 21/05/2016 REM Author: Christian d'Heureuse; shian (See License below) ' Notes: ' 1. Translated from VBasic to SmallBASIC (shian). ' ' 2. Useful for IMAGE keyword, and for any binary-to-text encoding/decoding. ' Base64 is often used to embed binary data in source code. ' ' 3. Since this is a translated code, I did not add much comments about the ' encoding/decoding method... So for more details about it see: ' https://en.wikipedia.org/wiki/Base64 ' ' 4. License: ' - A Base64 Encoder/Decoder. This module is used to encode and decode data ' in Base64 format as described in RFC 1521. ' - Home page: www.source-code.biz. ' - Code from: http://www.source-code.biz/snippets/vbasic/12.htm ' - License: GNU/LGPL (www.gnu.org/licenses/lgpl.html). ' - Copyright 2007: Christian d'Heureuse, Inventec Informatik AG, Switzerland. ' - This module is provided "as is" without warranty of any kind. ' ' -- Start Demo code --- --- --- --- --- --- --- --- --- --- --- ' ' ' ( See also: http://smallbasic.sourceforge.net/?q=comment/1398#comment-1398 ) ' ' Import base64 ' (Import from another .bas file) ' ' Const FILE = "SB.png" ' (Change it to any other file name) ' ' ' Example using a "file name": ' s = base64.Encode_Base64(FILE) ' Encode 1-D bytes-array to Base64-string ' a = base64.Decode_Base64(s) ' Decode Base64-string to 1-D bytes-array ' ' i = Image(a) ' Convert 1-D bytes-array to image ' i.Show(10, 10) ' Show image at location (x, y) ' Showpage ' ' ' Example using a file # (opened for input): ' Open FILE For Input As #1 ' s = base64.Encode_Base64(1) ' Encode 1-D bytes-array to Base64-string ' Close #1 ' a = base64.Decode_Base64(s) ' Decode Base64-string to 1-D bytes-array ' ' i = Image(a) ' Convert 1-D bytes-array to image ' i.Show(30, 30) ' Show image at location (x, y) ' Showpage ' ' ' Example using 1-D bytes-array (a): ' s = base64.Encode_Base64(a) ' Encode 1-D bytes-array to Base64-string ' a = base64.Decode_Base64(s) ' Decode Base64-string to 1-D bytes-array ' ' i = Image(a) ' Convert 1-D bytes-array to image ' i.Show(50, 50) ' Show image at location (x, y) ' Showpage ' ' Pause ' ' -- End Demo code --- --- --- --- --- --- --- --- --- --- --- --- Unit base64 Export Encode_Base64, Decode_Base64 ' Initialize the helper maps (this code executes only once at load time). Dim Map1(0 To 63) Dim Map2(0 To 127) i = 0 ' Set Map1 For c = 65 To 90: Map1(i) = c: i++: Next ' Asc("A") To Asc("Z") For c = 97 To 122: Map1(i) = c: i++: Next ' Asc("a") To Asc("z") For c = 48 To 57: Map1(i) = c: i++: Next ' Asc("0") To Asc("9") Map1(i) = 43 : i++ ' Asc("+") Map1(i) = 47 : i++ ' Asc("/") ' Set Map2 For i = 0 To 127 Do Map2(i) = 255 For i = 0 To 63 Do Map2(Map1(i)) = i ' Encodes a 1-D bytes array (integers) into Base64 format string. ' No blanks or line breaks are inserted. ' Parameters: ' InData 1-D bytes array containing the data bytes to be encoded; ' or, "File_Name" string to load into 1-D bytes array; ' or, File-Number (opened-for-input) to load into 1-D bytes array. ' Returns: a string with the Base64 encoded data (that you can embed in ' your source code). Func Encode_Base64(InData) Local Out ' (As Byte) Local ODataLen, OLen, ILen ' (As Long) Local ip0, ip, op ' (As Long) Local i0, i1, i2 ' (As Byte) Local o0, o1, o2, o3 ' (As Byte) Local s, i, fn, f ' as SmallBASIC... If Isarray(InData) Then ' 1-D bytes array (integers) supplied ILen = Len(InData) ' Make life easier by loading 1-D bytes array from file: Else f = Isnumber(InData) ' Set flag to close file If f Then ' An opened file # (For Input) supplied fn = InData Else ' A "filename" supplied fn = Freefile Open InData For Input As #fn Fi ILen = Lof(fn) Dim InData(1 To ILen) ' (It's much faster to allocate space first!) For i = 1 To ILen Do InData(i) = Bgetc(fn) If Not f Then Close #fn ' (Don't close file if File # supplied) Fi If ILen = 0 Then Encode_Base64 = "": Exit Func ODataLen = (ILen * 4 + 2) \ 3 ' Output length without padding OLen = ((ILen + 2) \ 3) * 4 ' Output length including padding Dim Out(0 To OLen - 1) ip0 = LBound(InData) ' Encode base64 bytes array (See Wikipedia for this...): While ip < ILen i0 = InData(ip0 + ip): ip++ If ip < ILen Then i1 = InData(ip0 + ip): ip++ Else i1 = 0 If ip < ILen Then i2 = InData(ip0 + ip): ip++ Else i2 = 0 o0 = i0 \ 4 o1 = ((i0 Band 3) * 0x10) Bor (i1 \ 0x10) o2 = ((i1 Band 0xF) * 4) Bor (i2 \ 0x40) o3 = i2 Band 0x3F Out(op) = Map1(o0): op++ Out(op) = Map1(o1): op++ Out(op) = Iff(op < ODataLen, Map1(o2), 61): op++ ' 61 is Asc("=") Out(op) = Iff(op < ODataLen, Map1(o3), 61): op++ ' 61 is Asc("=") Wend s = "": For i In Out Do s += Chr(i) ' Bytes-to-String Encode_Base64 = s End Func ' Decodes a string from Base64 format. ' Parameters ' s a Base64 String to be decoded. ' Returns: a 1-D array containing the decoded data bytes (integers). Func Decode_Base64(s) Local IBuf, Out ' (As Byte array) Local i0, i1, i2, i3 ' (As Byte) Local b0, b1, b2, b3 ' (As Byte) Local o0, o1, o2 ' (As Byte) Local OLen, ip, op ' (As Long) Local ILen = Len(s) ' (As Long) Local i ' as SmallBASIC... If (ILen Mod 4) Or (ILen = 0) Then ' Data error Throw "Length of Base64 encoded input string is not a multiple of 4." Fi Dim IBuf(0 To ILen - 1) For i = 1 To ILen Do IBuf(i - 1) = Asc(Mid(s, i, 1)) ' String-to-Bytes While ILen > 0 If IBuf(ILen - 1) <> 61 Then Exit Loop ' 61 is Asc("=") ILen-- Wend OLen = (ILen * 3) \ 4 Dim Out(0 To OLen - 1) ' 1-D bytes array ' Decode base64 bytes array (See Wikipedia for this...): While ip < ILen i0 = IBuf(ip): ip++ i1 = IBuf(ip): ip++ If ip < ILen Then i2 = IBuf(ip): ip++ Else i2 = 65 ' 65 is Asc("A") If ip < ILen Then i3 = IBuf(ip): ip++ Else i3 = 65 ' 65 is Asc("A") If i0 > 127 Or i1 > 127 Or i2 > 127 Or i3 > 127 Then Throw "Illegal character in Base64 encoded data." ' Data error Fi b0 = Map2(i0) b1 = Map2(i1) b2 = Map2(i2) b3 = Map2(i3) If b0 > 63 Or b1 > 63 Or b2 > 63 Or b3 > 63 Then Throw "Illegal character in Base64 encoded data." ' Data error Fi o0 = (b0 * 4) Bor (b1 \ 0x10) o1 = ((b1 Band 0xF) * 0x10) Bor (b2 \ 4) o2 = ((b2 Band 3) * 0x40) Bor b3 Out(op) = o0: op++ If op < OLen Then Out(op) = o1: op++ If op < OLen Then Out(op) = o2: op++ Wend Decode_Base64 = Out End Func